// $Id: output_header.hpp 2 2009-09-02 08:47:42Z joseph2002 $
/*
 * Copyright 2009 Joseph Wu
 * Distributed under the Boost Software License, Version 1.0.
 * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
 *
 * For more information, see http://xpcomplus.sourceforge.net
 */

#ifndef XPGEN_OUTPUT_HEADER_HPP
#define XPGEN_OUTPUT_HEADER_HPP

#include <iosfwd>
#include <vector>
#include <xpgen/output_cpp.hpp>

namespace xpgen {

struct interface_decl;
struct constant_decl;
struct method_decl;
struct param_decl;

class output_header : public output_cpp
{
public:
    explicit output_header(output* prev = 0);
    virtual ~output_header();

    // options
    bool raw_interfaces;
    bool exact_includes;

    std::string get_filename(interface_decl* itf) const;
    std::string get_type_info_type(interface_decl* itf) const;
    std::string get_interface_proxy_type(interface_decl* itf) const;

protected:
    virtual void do_reset();
    virtual void do_prologue();
    virtual void do_epilogue();
    virtual void do_interface(interface_decl* itf);

private:
    unsigned get_param_include_flags(param_decl* param) const;
    unsigned get_include_flags(interface_decl* itf) const;

    void do_interface_reference(std::ostream& os, interface_decl* itf);
    void do_interface_def(std::ostream& os, interface_decl* itf);
    void do_interface_type_info(std::ostream& os, interface_decl* itf);
    void do_interface_proxy_def(std::ostream& os, interface_decl* itf);

    void do_constant(std::ostream& os, constant_decl* constant);
    void do_method(std::ostream& os, method_decl* method);
    void do_method_qi(std::ostream& os, method_decl* method);
    void do_method_qi_templ_decl(std::ostream& os, method_decl* method);
    void do_method_qi_signature(std::ostream& os, method_decl* method);
    void do_method_qi_body(std::ostream& os, method_decl* method);

    void do_proxy_method(std::ostream& os, method_decl* method);
    void do_proxy_method_signature(std::ostream& os, method_decl* method);
    void do_proxy_method_body(std::ostream& os, method_decl* method);
    void do_proxy_retval_decl(std::ostream& os, param_decl* param);
    void do_proxy_pstring_size_decl(std::ostream& os);
    void do_proxy_pstring_size_commit(std::ostream& os);

    void do_proxy_method_qi(std::ostream& os, method_decl* method);
    void do_proxy_method_qi_signature(std::ostream& os, method_decl* method);
    void do_proxy_method_qi_signature2(std::ostream& os, method_decl* method);
    void do_proxy_method_qi_body(std::ostream& os, method_decl* method);
    void do_proxy_method_qi_body2(std::ostream& os, method_decl* method);

    void do_param_arg(std::ostream& os, param_decl* param);
    void do_param_arg_qi(std::ostream& os, param_decl* param);
    void do_proxy_param_arg(std::ostream& os, param_decl* param);
    void do_proxy_param_arg_qi(std::ostream& os, param_decl* param);

    std::string get_param_type_name_qi(param_decl* param) const;
    std::string get_proxy_param_type_name_qi(param_decl* param) const;

    // Saved for current proxy method
    std::vector<param_decl*> pstring_size_params_;
};

} // namespace xpgen

#endif // XPGEN_OUTPUT_HEADER_HPP
